package com.atguigu.gulimall.product.service.impl;

import com.atguigu.gulimall.product.entity.Category;
import com.atguigu.gulimall.product.entity.PmsAttr;
import com.atguigu.gulimall.product.entity.PmsAttrAttrgroupRelation;
import com.atguigu.gulimall.product.entity.PmsAttrGroup;
import com.atguigu.gulimall.product.dao.CategoryMapper;
import com.atguigu.gulimall.product.dao.PmsAttrAttrgroupRelationMapper;
import com.atguigu.gulimall.product.dao.PmsAttrGroupMapper;
import com.atguigu.gulimall.product.dao.PmsAttrMapper;
import com.atguigu.gulimall.product.service.ICategoryService;
import com.atguigu.gulimall.product.service.IPmsAttrService;
import com.atguigu.gulimall.product.vo.AttrGroupRelationVO;
import com.atguigu.gulimall.product.vo.AttrRespVO;
import com.atguigu.gulimall.product.vo.AttrVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.contant.ProductContant;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品属性 服务实现类
 * </p>
 *
 * @author szh
 * @since 2020-12-01
 */
@Service
public class PmsAttrServiceImpl extends ServiceImpl<PmsAttrMapper, PmsAttr> implements IPmsAttrService {
	@Autowired
	private PmsAttrAttrgroupRelationMapper attrGroupRelationMapper;

	@Autowired
	private PmsAttrGroupMapper attrGroupMapper;
	@Autowired
	private CategoryMapper categoryMapper;

	@Autowired
	private ICategoryService categoryService;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		IPage<PmsAttr> page = this.page(
				new Query<PmsAttr>().getPage(params),
				new QueryWrapper<PmsAttr>()
		);

		return new PageUtils(page);
	}

	@Override
	@Transactional
	public void saveAttr(AttrVO attr) {
		PmsAttr pmsAttr = new PmsAttr();
		// 利用属性拷贝
		BeanUtils.copyProperties(attr,pmsAttr);
		// 1-保存基本属性
		this.save(pmsAttr);
		// 2- 保存关联关系
		if (attr.getAttrType() == ProductContant.AttrEnum.ATTR_TYPE_BASE.getCode() && attr.getAttrGroupId()!=null){
			PmsAttrAttrgroupRelation attrgroupRelation = new PmsAttrAttrgroupRelation();
			attrgroupRelation.setAttrGroupId(attr.getAttrGroupId());
			attrgroupRelation.setAttrId(pmsAttr.getAttrId());
			attrGroupRelationMapper.insert(attrgroupRelation);
		}



	}
	// todo 这个 还不能做到模糊查询，前端 传输的有问题  r/base/list/0?t=1608974439231&page=1&limit=10&key=6
	@Override
	public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String type) {
		QueryWrapper<PmsAttr> queryWrapper = new QueryWrapper<PmsAttr>()
				.eq("attr_type","base".equalsIgnoreCase(type)?ProductContant.AttrEnum.ATTR_TYPE_BASE.getCode():ProductContant.AttrEnum.ATTR_TYPE_SALE.getCode());
		if (catelogId !=0){
			queryWrapper.eq("catelog_id",catelogId);
			String key = (String) params.get("key");
			if (StringUtils.isNotBlank(key)){
				// 根据 attr_id 或者 模糊查询 attr_name
				queryWrapper.and((wrapper)->{
					wrapper.eq("attr_id",key).or().like("attr_name",key);
				});
			}
		}
		IPage<PmsAttr> page = this.page(
				new Query<PmsAttr>().getPage(params),
				queryWrapper
		);
		PageUtils pageUtils = new PageUtils(page);
		/*
		* 不建议进行连表查询，当表中数据很大的时候，笛卡尔积太过于大。A表数据 1w B表 1 万
		* */
		List<PmsAttr> records = page.getRecords();
		List<AttrRespVO> respVOList = records.stream().map((attrEntity) -> {
			AttrRespVO attrRespVO = new AttrRespVO();
			BeanUtils.copyProperties(attrEntity, attrRespVO);
			// attrRespVO 设置上 分类和分组的名字
			if ("base".equalsIgnoreCase(type)){
				PmsAttrAttrgroupRelation attrId = attrGroupRelationMapper.selectOne(new QueryWrapper<PmsAttrAttrgroupRelation>().eq("attr_id", attrEntity.getAttrId()));
				if (attrId != null && attrId.getAttrGroupId()!=null) {
					PmsAttrGroup attrGroup = attrGroupMapper.selectById(attrId.getAttrGroupId());
					attrRespVO.setGroupName(attrGroup.getAttrGroupName());
				}
			}
			// 拿到分类名称
			Category category = categoryMapper.selectById(attrEntity.getCatelogId());
			if (category != null) {
				attrRespVO.setCatelogName(category.getName());
			}
			return attrRespVO;
		}).collect(Collectors.toList());
		pageUtils.setList(respVOList);
		return  pageUtils;
	}

	@Override
	public AttrRespVO getAttrInfo(Long attrId) {
		AttrRespVO respVO = new AttrRespVO();

		PmsAttr attrEntity = this.getById(attrId);
		// 相互拷贝
		BeanUtils.copyProperties(attrEntity,respVO);

		if(attrEntity.getAttrType() ==ProductContant.AttrEnum.ATTR_TYPE_BASE.getCode() ){
			// 设置分组
			PmsAttrAttrgroupRelation attrgroupRelation = attrGroupRelationMapper.selectOne(new QueryWrapper<PmsAttrAttrgroupRelation>().eq("attr_id", attrEntity.getAttrId()));
			if (attrgroupRelation !=null){
				respVO.setAttrGroupId(attrgroupRelation.getAttrGroupId());
				PmsAttrGroup attrGroup = attrGroupMapper.selectById(attrgroupRelation.getAttrGroupId());
				if (attrGroup != null){
					respVO.setGroupName(attrGroup.getAttrGroupName());
				}
			}
		}

		// 2-设置分类信息
		Long catelogId = attrEntity.getCatelogId();
		Long[] catelogPath = categoryService.findCatelogPath(catelogId);
		respVO.setCatelogPath(catelogPath);

		Category categoryEntity = categoryMapper.selectById(catelogId);
		if (categoryEntity != null){
			respVO.setCatelogName(categoryEntity.getName());
		}



		return respVO;
	}

	@Override
	public void updateAttr(AttrVO attrVO) {
		// 基本属性修改
		PmsAttr attrEntity = new PmsAttr();
		BeanUtils.copyProperties(attrVO,attrEntity);
		this.updateById(attrEntity);
		// 判断是不是基本类型，如果是基本类型，修改分组
		if(attrEntity.getAttrType() ==ProductContant.AttrEnum.ATTR_TYPE_BASE.getCode() ){
			// 1-修改分组关联
			PmsAttrAttrgroupRelation relationEntity = new PmsAttrAttrgroupRelation();
			relationEntity.setAttrGroupId(attrVO.getAttrGroupId());
			relationEntity.setAttrId(attrVO.getAttrId());
			Integer count = attrGroupRelationMapper.selectCount(new QueryWrapper<PmsAttrAttrgroupRelation>()
					.eq("attr_id", attrVO.getAttrId()));
			if (count>0){
				attrGroupRelationMapper.update(relationEntity,new QueryWrapper<PmsAttrAttrgroupRelation>()
						.eq("attr_id",attrVO.getAttrId()));

			}else {
				attrGroupRelationMapper.insert(relationEntity);
			}


		}

	}

	@Override
	public List<PmsAttr> getRelationAttr(Long attrgroupId) {
		List<PmsAttrAttrgroupRelation> relationList = attrGroupRelationMapper.selectList(new QueryWrapper<PmsAttrAttrgroupRelation>().eq("attr_group_id", attrgroupId));
		List<Long> attrIdList = relationList.stream().map((relation) -> {
			return relation.getAttrId();
		}).collect(Collectors.toList());
		if (attrIdList.size()==0 || attrIdList ==null){
			return null;
		}
		List<PmsAttr> attrEntities = this.listByIds(attrIdList);
		return attrEntities;
	}

	@Override
	public void deleteRelation(AttrGroupRelationVO[] vos) {
		List<PmsAttrAttrgroupRelation> RelationEntitis = Arrays.asList(vos).stream().map((item) -> {
			PmsAttrAttrgroupRelation relationEntity = new PmsAttrAttrgroupRelation();
			BeanUtils.copyProperties(item, relationEntity);
			return relationEntity;
		}).collect(Collectors.toList());
		attrGroupRelationMapper.deleteBatchRelation(RelationEntitis);
	}

	// todo 这个有点难度，课程81
	@Override
	public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrgroupId) {
		//1-当前分组只能关联自己所属的分类里面的属性
		PmsAttrGroup attrGroupEntity = attrGroupMapper.selectById(attrgroupId);
		// 从这个组下拿分类id
		Long catelogId = attrGroupEntity.getCatelogId();

		// 2- 当前分组只能关联别的分组美元引用的属性
		// 2.1- 当前分类的其他分组（不包括自己）
		List<PmsAttrGroup> attrGroupList = attrGroupMapper.selectList(new QueryWrapper<PmsAttrGroup>().eq("catelog_id", catelogId));
		// 拿到所有 attrGroupId
		List<Long> attrGroupIdList = attrGroupList.stream().map(item -> {
			return item.getAttrGroupId();
		}).collect(Collectors.toList());
		// 2.2 -这些分组关联的属性，去中间表去查
		List<PmsAttrAttrgroupRelation> relationList = attrGroupRelationMapper.selectList(new QueryWrapper<PmsAttrAttrgroupRelation>().in("attr_group_id", attrGroupIdList));
		// 拿到 有关联属性记录的 attr表的主键 id
		List<Long> attrIdList = relationList.stream().map(item -> {
			return item.getAttrId();
		}).collect(Collectors.toList());
		// 2.3-从当前分类的所有属性中，移除这些已经被关联的属性.注意：并且不是是销售属性的记录，加 是基本属性这个条件
		QueryWrapper<PmsAttr> queryWrapper = new QueryWrapper<PmsAttr>()
				.eq("catelog_id", catelogId)
				.eq("attr_type", ProductContant.AttrEnum.ATTR_TYPE_BASE.getCode());
		if (attrIdList !=null && attrIdList.size()>0){
			// 这个还得是不是当前组的数据
			queryWrapper.notIn("attr_id",attrIdList);
		}
		// 还要搜索框中的功能
		String key = (String) params.get("key");
		if(!StringUtils.isEmpty(key)){
			queryWrapper.and((w)->{
				w.eq("attr_id",key).or().like("attr_name",key);
			});
		}
		IPage<PmsAttr> page = this.page(new Query<PmsAttr>().getPage(params), queryWrapper);
		PageUtils pageUtils = new PageUtils(page);

		return pageUtils;
	}

}
